package pers.cz.io;

import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.util.ClassUtils;

import javax.servlet.http.HttpServletResponse;
import java.io.*;
import java.net.URLEncoder;
import java.nio.ByteBuffer;
import java.nio.channels.FileChannel;
import java.util.LinkedHashMap;
import java.util.Map;

/**
 * @program: PostGirl-panent
 * @description: IO工具类
 * @author: Cheng Zhi
 * @create: 2022-06-29 17:56
 **/
public class IOUtils {

    private static Logger logger = LoggerFactory.getLogger(IOUtils.class);

    /**
     * 关闭资源
     * @param input
     */
    public static void close(Closeable input) {
        if (input != null) {
            try {
                input.close();
            } catch (IOException e) {
                logger.error("资源关闭异常：", e);
            }
        }
    }
    /**
     * 根据枚举类型获取文件夹路径
     * @param filePathEnum
     * @return
     */
    public static String getFoldPath(FoldPathEnum filePathEnum) {
        String path = "";
        // todo 如何判断是生成环境还是测试环境
        try {
            path = ClassUtils.getDefaultClassLoader().getResource(filePathEnum.getFilePath()).getPath();  // 生产
            if (path == null) {
                path  = IOUtils.class.getClass().getResource(filePathEnum.getFilePath()).getPath();
            }
        } catch (Exception e) {
            path  = IOUtils.class.getClass().getResource(filePathEnum.getFilePath()).getPath();
        }
        //String path  = this.getClass().getResource(templatePath).getPath();
        return path;
    }

    /**
     * 一般用于controller文件下载
     * @param response
     * @param file
     * @throws IOException
     */
    public static void downFileWithNetWork(HttpServletResponse response, File file) throws IOException {
        if (file == null) {
            throw new IOException();
        }
        // 获取文件名
        String filename = file.getName();

        // 将文件写入输入流
        FileInputStream fileInputStream = new FileInputStream(file);
        InputStream fis = new BufferedInputStream(fileInputStream);
        byte[] buffer = new byte[fis.available()];
        fis.read(buffer);
        fis.close();

        // 清空response
        response.reset();
        // 设置response的Header
        response.setCharacterEncoding("UTF-8");
        response.addHeader("Content-Disposition", "attachment;filename=" + URLEncoder.encode(filename, "UTF-8"));
        // 告知浏览器文件的大小
        response.addHeader("Content-Length", "" + file.length());
        OutputStream outputStream = new BufferedOutputStream(response.getOutputStream());
        response.setContentType("application/octet-stream");
        outputStream.write(buffer);
        outputStream.flush();

        // 删除文件；
        file.delete();
    }
    /**
     * 获得Reader
     *
     * @param is
     * @return
     * @throws IOException
     */
    public static BufferedReader getReader(InputStream is) {
        if (is == null)
            return null;
        BufferedReader bufferedReader = new BufferedReader(
                new InputStreamReader(is));

        return bufferedReader;
    }

    /**
     * 将bufferedReader中的内容读取出来
     * @param bf
     * @return
     * @throws IOException
     */
    public static Map<String, String> loadProperties(BufferedReader bf) throws IOException {

        Map<String, String> map = new LinkedHashMap<>();

        bf.lines().forEach(line->{
            if (line == null || "".equals(line)) {
                return;
            }
            String[] split = line.split("=");
            map.put(split[0].trim(), split[1].trim());
        });

        return map;
    }

    /**
     * 直接从文件中读取字符并存放到map中
     * @param fileInputStream
     * @return
     * @throws IOException
     */
    public static Map<String, String> loadProperties(FileInputStream fileInputStream) throws IOException {

        Map<String, String> map = new LinkedHashMap<>();
        try (FileChannel channel = fileInputStream.getChannel();) {
            ByteBuffer byteBuffer = ByteBuffer.allocate(1024);
            // 按照字节来读取
            while (channel.read(byteBuffer) > 0) {
                byteBuffer.flip();
                readLine(byteBuffer, map);
            }
        }

        return map;
    }

    /**
     * 从缓存区中读取一行,存放到map中
     * @param byteBuffer
     */
    private static void readLine(ByteBuffer byteBuffer, Map<String, String> map) {
        // 是否为注释行
        boolean isCommendLine = false;
        // 是否为新行
        boolean isNewLine = false;

        String key = "";
        String value = "";

        StringBuilder sb = new StringBuilder();
        while(byteBuffer.hasRemaining()) {
            char c = (char) byteBuffer.get();

            if (!key.equals("") && !value.equals("")) {
                map.put(key,value);
                key = "";
                value = "";
            }

            // asdfghjk\nadfadfadf\nerer
            if (c == '\n' || c == '\r') {
                isNewLine = true;
                isCommendLine = false; // 如果遇到换行则重新判断是否为注释行
            } else {
                isNewLine = false;
            }

            // 如果第一个字符是空格，tab制表符则跳过
            if (c == ' ' || c == '\t') {
                continue;
            }

            // 如果去除了空格之外是#或者！则表示注释行,注释行之后的内容不处理，直到遇到换行或者回车
            if (c == '#' || c == '!') {
                isCommendLine = true;
            }

            // 判断如果是新行，看是不是为空则不处理
            if (isNewLine) {
                // 如果是新行，且字符串长度为0,则不处理
                int length = sb.length();
                if (length == 0) {
                    continue;
                }
                isCommendLine = false;
                isNewLine = false;
                value = sb.toString();
                sb = new StringBuilder();
                continue;
            }

            if (!isCommendLine) {
                // 如果遇到 = ： 则认为要分割,前面的为key, 后面的为value
                if (c == '=' || c == ':') {
                    key = sb.toString();
                    // 重置sb
                    sb = new StringBuilder();
                    continue;
                }
                sb.append(c);
            }

        }
    }


    public static void main(String[] args) throws Exception {

        Resource resource = new ResourceLoader().loadResource("jef.properties");
        //Map<String, String> stringStringMap = loadProperties(getReader(resource.getInputStream()));
        Map<String, String> stringStringMap1 = loadProperties(resource.getFileInputStream());

        System.out.println(stringStringMap1);
        char[] chars = new char[1024];
        chars[0] = 'n';
        chars[1] = 'a';
        chars[2] = 'm';
        chars[3] = 'e';
        chars[4] = '=';
        chars[5] = 'c';
        chars[6] = 'z';
        chars[7] = ';';

        //String s = new String(chars);
        //System.out.println(s);

        StringBuilder stringBuilder = new StringBuilder();
        stringBuilder.append('n');
        stringBuilder.append('a');
        stringBuilder.append('m');
        stringBuilder.append('e');
        stringBuilder.append('=');
        stringBuilder.append('c');
        stringBuilder.append('z');
        System.out.println(stringBuilder.toString());
    }
}
